/**
 * Copyright (C) 2025 pony working team
 * SPDX-License-Identifier: MulanPSL-2.0
 */

/* define to prevent recursive inclusion -------------------------------------*/
#ifndef __TESTER_H__
#define __TESTER_H__

/* includes (standard library, system) ---------------------------------------*/
/* includes (other library) --------------------------------------------------*/
/* includes (project) --------------------------------------------------------*/
#include <x_compiler.h>
/* includes (local) ----------------------------------------------------------*/

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* defines -------------------------------------------------------------------*/

#define TESTER_SECTION tester

/* typedefs ------------------------------------------------------------------*/

typedef struct tester_statistics {
    uint32_t totals;
    uint32_t fails;
} tester_statistics_t;

typedef struct tester_case {
    const char *name;
    uint32_t timeout;
    void (*entry)(struct tester_case *);
    void (*setup)(void);
    void (*teardown)(void);
    tester_statistics_t *stats;
} tester_case_t;

/* macro ---------------------------------------------------------------------*/

#define __TESTER_CASE_DEF(name, entry, setup, teardown, timeout, tag)                              \
    static tester_statistics_t __CONCAT(stats, __CONCAT(entry, tag));                              \
    const tester_case_t __CONCAT(entry, tag) __section__(TESTER_SECTION) = {                       \
        name, timeout, entry, setup, teardown, &__CONCAT(stats, __CONCAT(entry, tag))}

#define TESTER_CASE_DEF(name, entry, setup, teardown, timeout)                                     \
    __TESTER_CASE_DEF(name, entry, setup, teardown, timeout, __LINE__)

/* inlines -------------------------------------------------------------------*/
/* externs -------------------------------------------------------------------*/

extern char __section_start__(TESTER_SECTION)[];
extern char __section_end__(TESTER_SECTION)[];

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __TESTER_H__ */
